package com.example.config;

import com.example.entity.RestBean;
import com.example.entity.vo.response.AuthorizeVO;
import com.example.utils.JwtUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.SecurityFilterChain;

import java.io.IOException;

@Configuration
public class SecurityConfiguration {

    @Resource
    JwtUtils jwtUtils;
    /**
     * 配置Spring Security过滤器链
     *
     * @param httpSecurity HttpSecurity对象，用于配置安全策略
     * @return SecurityFilterChain 安全过滤器链配置
     * @throws Exception 配置过程中可能抛出的异常
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                // 配置请求授权规则
                .authorizeHttpRequests(conf -> conf
                        // 允许所有用户访问认证相关接口
                        .requestMatchers("/api/auth/**").permitAll()
                        // 其他所有请求都需要认证
                        .anyRequest().authenticated()
                )
                // 配置表单登录
                .formLogin(conf -> conf
                        // 设置登录处理URL
                        .loginProcessingUrl("/api/auth/login")
                        // 设置登录失败处理器
                        .failureHandler(this::onAuthenticationFailure)
                        // 设置登录成功处理器
                        .successHandler(this::onAuthenticationSuccess)
                )
                // 配置登出
                .logout(conf -> conf

                        // 设置登出URL
                        .logoutUrl("/api/auth/logout")
                        // 设置登出成功处理器
                        .logoutSuccessHandler(this::onLogoutSuccess)
                )
                // 禁用CSRF保护
                .csrf(AbstractHttpConfigurer::disable)
                // 配置会话管理
                .sessionManagement(conf -> conf
                        // 设置会话创建策略为无状态
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                )
                .build();
    }

    /**
     * 认证成功后的处理方法
     *
     * @param request        HTTP请求对象
     * @param response       HTTP响应对象
     * @param authentication 认证对象，包含认证成功后的用户信息
     * @throws IOException      IO异常
     * @throws ServletException Servlet异常
     */
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        User user = (User) authentication.getPrincipal();
        AuthorizeVO vo = new AuthorizeVO();
        vo.setExpire(jwtUtils.getExpirationDate());
        vo.setRole("");
        vo.setUsername("xiangming");
        vo.setToken(jwtUtils.createJwt(user,1111,"xiangming"));
        response.getWriter().write(RestBean.success(vo).asJsonString());
    }

    /**
     * 处理认证失败的情况
     *
     * @param request   HTTP请求对象，包含客户端发送的请求信息
     * @param response  HTTP响应对象，用于向客户端发送响应数据
     * @param exception 认证异常对象，包含认证失败的具体信息
     * @throws IOException      当输入输出操作发生错误时抛出
     * @throws ServletException 当Servlet处理发生错误时抛出
     */
    public void onAuthenticationFailure(HttpServletRequest request,
                                        HttpServletResponse response,
                                        AuthenticationException exception) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(RestBean.failure(401, exception.getMessage()).asJsonString());
    }


    public void onLogoutSuccess(HttpServletRequest request,
                                HttpServletResponse response,
                                Authentication authentication) throws IOException, ServletException {

    }
}
